package tm.testing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import com.jme.curve.PolylineCurve;
import com.jme.math.Vector3f;
import com.jme.scene.Spatial;

public class Track {
	
	protected ArrayList<Coordinate> track;
	protected ArrayList<Spatial> spatials;
	protected HashMap<Coordinate, Spatial> ref;
	private String identifier;
	private PolylineCurve curve;
	protected MapGrid mapGrid;
	
	public Track(String id, MapGrid mg) {
		identifier = id;
		track = new ArrayList<Coordinate>();
		spatials = new ArrayList<Spatial>();
		ref = new HashMap<Coordinate, Spatial>();
		mapGrid = mg;
	}
	
	public void addField(Coordinate c) {
		track.add(c);
	}
	
	public String getIdentifier() {
		return identifier;
	}
	
	public PolylineCurve getCurve() {
		return curve;
	}
	
	public void updateCurve() {
		// TODO Here we get a JMEException, Curve.java:100, PolylinCurve.java:69
		// 		in case we're trying to call updateCurve() on a track with only
		//		one track segment, as there must be at least two control points
		//		in order to initialize a curve. Solution needed, should be available
		//		with only one segment(?)
		
		Vector3f[] points = new Vector3f[track.size()];
		for(int i=0; i<track.size(); i++) {
			try {
				points[i] = mapGrid.getElementCoord(track.get(i).getX(),track.get(i).getY(), 150.0f);
			} catch (MapElementIndexOutOfBoundsException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
			curve = new PolylineCurve(identifier+"_TrackCurve",points);
			curve.setSteps(track.size());
	}
	
	
	
	public Coordinate getCoordinateAt(int index) {
		return track.get(index);
	}
	
	public int getTotalLength() {
		return track.size();
	}	
	
	
	protected void clearSpatials() {
		spatials.clear();
		ref.clear();
	}
	
	protected Spatial getSpatialByCoordinate(Coordinate c) {
		// TODO Maybe implement something in case of an invalid coordinate... exception
		
		Set<Coordinate> coords = ref.keySet();
		Iterator<Coordinate> itr = coords.iterator();
		
		while(itr.hasNext()) {
			Coordinate tmp = itr.next();
			if(tmp.getX()==c.getX() && tmp.getY()==c.getY()) {
				return ref.get(tmp);
			}
		}
		return null;
	}
	
	public boolean containsCoordinate(Coordinate c) {
		Iterator<Coordinate> itr = track.iterator();
		while(itr.hasNext()) {
			Coordinate tmp = itr.next();
			if(tmp.getX()==c.getX() && tmp.getY()==c.getY()) {
				return true;
			}
		}
		return false;
	}
	
	public void removeField(Coordinate c) {
		Iterator<Coordinate> itr = track.iterator();
		while(itr.hasNext()) {
			Coordinate tmp = itr.next();
			if(tmp.getX()==c.getX() && tmp.getY()==c.getY()) {
				track.remove(tmp);
				// TODO Reconsider that. If it is theoretically possible to have one element twice in list,
				//		the following line of code would be an epic fail.
				return;
			}
		}
	}
}
